<?php
if (!defined('APP') or !constant('APP')) die('Direct access not allowed!');
ini_set('display_errors', 1); 
ini_set('log_errors', 1); 

class UserModel {
    
    const COMMENT_INC = 1;
    const COMMENT_DEC = 2;
   
    public static function checkPrivileges($privs)
    {
        //if(!intval(UserModel::isLoggedIn())) return false;
        
        $query = "SELECT privs FROM users WHERE privs = :privs AND id=:id;";
        $result = DB::getPDO()->prepare($query);
        $result->execute(array(
            ':privs' => $privs,
            ':id'    => intval(UserModel::isLoggedIn()),
            ));  
        $result = $result->fetch();
        
        
        if (sizeof($result) < 1) { return false; }
        
        if ($result['privs'] == $privs) return true;
        
        return false;   
    }
    
    private static function existByIdAndEmail($id, $email)
    {
        $query = "SELECT id FROM users WHERE id = :id AND email = :email;";
        $result = DB::getPDO()->prepare($query);
        $result->execute(array(
            ':id' => intval($id),
            ':email' => htmlspecialchars($email)
            ));  
        $result = $result->fetchAll();
        
        if (sizeof($result) < 1) { return false; }
        
        return true;   
    }
    
    private static function exist($login)
    {
        $query = "SELECT id FROM users WHERE login = :login;";
        $result = DB::getPDO()->prepare($query);
        $result->execute(array(
            ':login' => $login           
            ));  
        $result = $result->fetchAll();
        
        if (sizeof($result) < 1) { return false; }
        
        return true;   
    }

    /*
     * Loguje użytwkonika
     */
    public static function login($login, $password)
    {
        
        $query = "SELECT id, password, salt, is_active, birth_date FROM users WHERE login = :login;";
        $result = DB::getPDO()->prepare($query);
        $result->execute(array(
            ':login' => trim(htmlspecialchars($login))
            ));  
        $result = $result->fetch();
                
        if (empty($result))
        {
            flash_message::setMessage("Podałeś nie prawidłowe dane. Spróbuj jeszcze raz.");
            System::redirect(View::getRoot()."/index.php?controller=index&action=index");
            die();
        }
       
        if (is_array($result) && intval($result['is_active'])==0) {
            flash_message::setMessage("Użytkownik nie został jeszcze aktywowany. Na adres twojej poczty został przesłany mail z linkiem aktywacyjnym.");
            System::redirect(View::getRoot()."/index.php?controller=index&action=index");
            die(); 
        }
                  
        $hash = hash('sha256', $result['salt'] . hash('sha256', trim($password)));
       
        if($hash != $result['password']) //incorrect password
        {
            self::logout(false);
            flash_message::setMessage("Password not valid");
            System::redirect(View::getRoot()."/index.php?controller=index&action=index");
            die();
        }        
        else
        {
            self::validateUser($result['id'], $login, $result['birth_date']);
            flash_message::setMessage("Użytkownik ".  htmlspecialchars($login) . " zalogowany poprawnie.");
        }
        return $result;
    }
    
    public static function countActiveUser()
    {
        $query = "SELECT COUNT(*) FROM users WHERE is_active = 1;";
        $result = DB::getPDO()->prepare($query);
        $result->execute();  
        $result = $result->fetch();
        
        if (sizeof($result) < 1) { return 0; }
        
        return $result['COUNT(*)'];   
    }
    
    private static function validateUser($userId, $login, $birth_date)
    {
        session_regenerate_id (true); //this is a security measure
        $_SESSION['valid'] = 1;
        $_SESSION['userid'] = $userId;      
        $_SESSION['login'] = $login;
        $_SESSION['birth_date'] = $birth_date;
    }
    
    public static function getPrivs()
    {
        return 0;
    }
    
    public static function getLogin()
    {
        if(isset($_SESSION['login']) && $_SESSION['login'])
            return $_SESSION['login'];
        return "";
    }
    /**
     * Sprawdza czy zalogowany
     * @return type 
     */
    public static function isLoggedIn()
    {
        if(isset($_SESSION['valid']) && $_SESSION['valid'])
            return $_SESSION['userid'];
        return false;
    }
    
    public static function logout($andRedirect = true)
    {
        $_SESSION = array(); //destroy all of the session variables
        session_destroy();
        if ($andRedirect) {
            flash_message::setMessage("Wylogowano z systemu");
            System::redirect(View::getRoot()."/index.php?controller=index&action=index");      
        }
    }
    
    /**
     * Tworzy uzytkownika w bazie danych
     * @param type $login
     * @param type $password1
     * @param type $password2 
     */
    public static function createUser($data)
    {
        $_error = 0;
        
        $resp = recaptcha_check_answer ('6Le0Jc8SAAAAAAVYhyHBWHFtUMvAHFGd1soZfDlG',
                                $_SERVER["REMOTE_ADDR"],
                                $_POST["recaptcha_challenge_field"],
                                $_POST["recaptcha_response_field"]);
        
        if (!$resp->is_valid) {
            flash_message::setMessage("Błedny captcha");
            System::redirect(View::getRoot()."/index.php?controller=index&action=index");
            return false;
        }
                              
        if(isset($data['login'])&&isset($data['password1'])&&isset($data['password2']))
        {
            $login = trim(htmlspecialchars($data['login']));
            $password1 = trim($data['password1']);
            $password2 = trim($data['password2']);
            $email = htmlspecialchars($data['email']);
        }
        else
        {
            flash_message::setMessage("Brak wymaganych danych");
            System::redirect(View::getRoot()."/uzytkownik/zarejestruj");
            return false;
        }
        
        if (!System::isValidEmail($email))
        {
            flash_message::setMessage("Nie prawidłowy adres email");
            System::redirect(View::getRoot()."/uzytkownik/zarejestruj");
            return false;
        }
        
        if (self::exist($login)) 
        {
            flash_message::setMessage("Użytkownik o takim loginie istnieje już bazie danych.");
            System::redirect(View::getRoot()."/uzytkownik/zarejestruj");
            return false;
        }
               
        //validate fields
        if ($password1 != $password2) $_error++;
        if (strlen($login) > 30 || strlen($login) < 3) $_error++;
        
        
        if ($_error>0) {
            flash_message::setMessage("Dane nie właściwe.");
            System::redirect(View::getRoot()."/uzytkownik/zarejestruj");
            return false;
        }
        
        $hash = hash('sha256', $password1);
        $salt = self::createSalt();
        $hash = hash('sha256', $salt . $hash);
                
        $query = "INSERT INTO `users` ( `birth_date`, `login`, `password`, `salt`, `privs`, `ip`, `email`, `is_active` )
        VALUES ( :birth_date, :login , :password , :salt, :privs, :ip, :email, :is_active );";
        $aBirth = explode('-',$data['birth_date']);
        $day = isset($aBirth[0]) ? $aBirth[0] : 0;
        $month = isset($aBirth[1]) ? $aBirth[1] : 0;
        $year = isset($aBirth[2]) ? $aBirth[2] : 2012;
        
        $aBirth = $year.'-'.$month.'-'.$day;
        
        $result = DB::getPDO()->prepare($query);
        $r = $result->execute(array(
            ':login'    => $login,
            ':password' => $hash,
            ':salt'     => $salt,
            ':privs'    => Privileges::USER,
            ':ip'       => System::getRealIpAddr(),
            ':email'    => $email,
            ':is_active'=> 0,
            ':birth_date'=> $aBirth
            ));   
        
        $id_user = DB::getPDO()->lastInsertId();
        
        if ($r < 1) { return false; }
        
        $html  = '<h2>Dziękujemy za rejestrację w serwisie zabij.pl</h2><hr><br/>';
        $html .= '<br>Przy rejestracji wykorzystałeś(aś) następujące dane:<br/><br/>';
        $html .= 'Login '.$login.'<br/>';
        $html .= 'Hasło: '.$password1.'<br/>';
        $html .= '<br/><br/>';
        $html .= 'Aby aktywować konto, proszę kliknąć w poniższy link: <br/><br/>';
        $html .= '<a href="'.View::getRoot().'/index.php?controller=user&action=activate&id_user='.$id_user.'&email='.$email.'">Aktywuj konto w serwisie zabij.pl</a>';
            
        
        Mail::sendPlain($email, "Użytkownik serwisu zabij.pl", $html);
        flash_message::setMessage("Dodano użytkownika do systemu");
        
        if (!$r) return false;
        return true;
    }        
    
    private static function createSalt()
    {
        $string = md5(uniqid(rand(), true));
        return substr($string, 0, 3);
    }
    
    public static function fetchAll()
    {
        $query = "SELECT * FROM `users` ORDER by login";
        $result = DB::getPDO()->prepare($query);
        $result->execute();  
        $result = $result->fetchAll();
        return $result;
    }
    
    // pobiera nazwę użytkownika
    // UWAGA!!! JESLI ISTNIEJE NICK TO POBIERA NICK UZYTKOWNIKA
    public static function getUserName($id)
    {
        $query = "SELECT * FROM `users` u, `users_profile` up WHERE `up`.`id_user`=`u`.`id` AND `up`.`id_user`=:id ";
        $result = DB::getPDO()->prepare($query);
        $result->execute(array(':id' => intval($id)));  
        $result = $result->fetch(); 
        
        if ($result) {          
            return $result['login'];       
        }
        
        return "Anonim";
    }
    
    public static function changePassword($oldPassword, $newPassword, $newPassword2)
    {
        if ($newPassword != $newPassword2) { return false; }
        
        $query = "SELECT password, salt FROM `users` WHERE `id`=:id";
        $result = DB::getPDO()->prepare($query);
        $result->execute(array('id' => UserModel::isLoggedIn()));  
        $result = $result->fetch();     
        
        
        $hash = hash('sha256', $result['salt'] . hash('sha256', trim($oldPassword)));
       
        if ($result['password'] != $hash)
        {
            return -2;
        }
        
        $hash = hash('sha256', $newPassword);
        $salt = self::createSalt();
        $hash = hash('sha256', $salt . $hash);
        
        $data = array();
        $data[':password'] = $hash;
        $data[':salt'] = $salt;  
        $data[':id_user'] = UserModel::isLoggedIn();
        
          
        $query = "UPDATE `users` SET `password`=:password, `salt`=:salt WHERE `id`=:id_user";                     
        $result = DB::getPDO()->prepare($query);        
        $result = $result->execute($data);      
                
        return $result;
    }
    
    public static function getUser($id)
    {
        $query = "SELECT * FROM `users` WHERE `id`=:id";
        $result = DB::getPDO()->prepare($query);
        $result->execute(array('id' => intval($id)));  
        $result = $result->fetch();        
        return $result;       
    }
    
    public static function getLoggedUser()
    {
        return self::getUser(UserModel::isLoggedIn());      
    }
    
    public static function activate($id_user, $email)
    {       
        $id_user = intval($id_user);
        
        if (($id_user == 0)||!self::existByIdAndEmail($id_user, $email)) return false;
                
        $data = array();
        
        $data[':is_active'] = 1;
        $data[':id_user'] = $id_user;
          
        $query = "UPDATE `users` SET `is_active`=:is_active WHERE `id`=:id_user";                     
        $result = DB::getPDO()->prepare($query);        
        return $result->execute($data);          
    
    }
    
    public static function updateBirthDate($userData)
    {
        
       // if (!isset($userData['id_user'])) return false;
        
        $data = array();
        
        $data[':birth_date'] = isset($userData['birth_date']) ? $userData['birth_date'] : '2012-01-01';
        $data[':id_user'] = UserModel::isLoggedIn();  
          
        $query = "UPDATE `users` SET `birth_date`=:birth_date WHERE `id`=:id_user";                     
        $result = DB::getPDO()->prepare($query);        
        return $result->execute($data);          
    }
    
    public static function update($userData)
    {
        
       // if (!isset($userData['id_user'])) return false;
        
        $data = array();
        
        $data[':privs'] = isset($userData['privs']) ? $userData['privs'] : Privileges::USER;
        $data[':email'] = isset($userData['email']) ? htmlspecialchars($userData['email']) : '';
        $data[':is_active'] = (isset ($userData['is_active'])&&$userData['is_active']=="on") ? 1 : 0;
        $data[':id_user'] = $userData['id_user'];  
          
        $query = "UPDATE `users` SET `privs`=:privs, `email`=:email, `is_active`=:is_active WHERE `id`=:id_user";                     
        $result = DB::getPDO()->prepare($query);        
        return $result->execute($data);          
    }
       
    public static function count_demot($mode)
    {   
        $data = array('id' => UserModel::isLoggedIn());
        
        $query = "SELECT `count_comments` FROM `users` WHERE `id`=:id";
        $result = DB::getPDO()->prepare($query);
        $result->execute($data);  
        $result = $result->fetch();        
        switch (intval($mode))
        {
            case UserModel::COMMENT_INC: $data['count_comments'] = intval($result['count_comments'])+1; break;
            case UserModel::COMMENT_DEC: $data['count_comments'] = intval($result['count_comments'])-1; break;
            default: $data['count_comments'] = intval($result['count_comments']);
        }
                    
        $query = "UPDATE `users` SET `count_comments`=:count_comments WHERE `id`=:id";   
            
        $result = DB::getPDO()->prepare($query);
        
        $result->execute($data);            
               
        return intval($data['count_comments']);
    }
}

?>